package com.vidmt.api.modules.sys.entity;

import java.util.Date;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.annotation.JSONField;
import com.google.common.collect.Maps;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.persistence.DataEntity;
import com.vidmt.api.common.anno.WebApiUse;
import com.vidmt.api.modules.sys.Enums.LvlType;
import com.vidmt.api.modules.sys.Enums.UserStatus;

public final class User extends DataEntity {
	private static final long serialVersionUID = 2L;
	private static final int MASK_LOCPRIVATE = 1;
	private static final int MASK_AVOIDDISTURB = 1 << 1;

	public static final Integer SEX_M = 1;
	public static final Integer SEX_F = 0;
	// private String accType;
	// private String account;
	private Long id;
	private String name;
	private String nick;
	private String email;
	private String phone;
	// TODO NOT USED
	@JSONField(serialize = false)
	private UserStatus status;
	private Integer sex;
	private java.sql.Date birth;
	private String signature;
	private String address;
	private String avatarUri;
	private String photoUri;
	// @JSONField(serialize = false)
	// private Integer flag;
	private Boolean avoidDisturb;
	private Boolean locPrivate;
	@JSONField(serialize = false)
	private Date createDate;
	@JSONField(serialize = false)
	private Date modifyDate;

	private LvlType lvl;
	/**
	 * 不保存在缓存中，每次获取都需要临时计算
	 */
	private transient Long lvlttl;// 单位:秒

	@WebApiUse
	@JSONField(format = "yyyy-MM-dd HH:mm:ss")
	private Date lvlEnd;
	@WebApiUse
	private List<Order> orders;
	@WebApiUse
	private Location location;
	@WebApiUse
	private transient boolean online;// 单位:秒
	/**
	 * 此属性用于那些要求不用特别精确的，不用持久化，重启后允许重置的属性，比如IOS推送消息的个数等. 为了提高效率，无需持久化,此属性是对
	 * OF自带properties的补充，但是不用持久化，因此提高了效率
	 */
	@JSONField(serialize = false)
	private Map<String, Object> props = Maps.newHashMap();

	public void setProp(String key, Object value) {
		if (value == null) {
			props.remove(key);
		} else {
			props.put(key, value);
		}
	}

	public Object getProp(String key, Object defaultValue) {
		return props.getOrDefault(key, defaultValue);
	}

	public boolean isAdmin() {
		return this.name != null && Global.getConfig("admin.adminName").equals(this.getName());
	}

	public boolean isSys() {
		return isAdmin();
	}

	@Override
	public boolean equals(Object obj) {
		User that = (User) obj;
		if (this.id != null) {
			return this.id.equals(that.id);
		} else if (this.name != null) {
			return this.name.equals(that.name);
		} else if (this.phone != null) {
			return this.phone.equals(that.phone);
		} else if (this.email != null) {
			return this.email.equals(that.email);
		}
		return false;
	}

	public User() {
	}

	public User(Long uid, Date createDate, Date modifyDate) {
		this.id = uid;
		this.createDate = createDate;
		this.modifyDate = modifyDate;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getNick() {
		return nick;
	}

	public void setNick(String nick) {
		this.nick = nick;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	@JSONField(serialize = false)
	public String getDisplayName() {
		if (this.nick != null) {
			return this.nick;
		} else if (this.name != null) {
			return this.name;
		} else if (this.phone != null) {
			return this.phone;
		}
		return this.id + "";
	}

	public Integer getSex() {
		return sex;
	}

	public void setSex(Integer sex) {
		this.sex = sex;
	}

	public java.sql.Date getBirth() {
		return birth;
	}

	public void setBirth(java.sql.Date birth) {
		this.birth = birth;
	}

	public String getSignature() {
		return signature;
	}

	public void setSignature(String signature) {
		this.signature = signature;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getAvatarUri() {
		return avatarUri;
	}

	public void setAvatarUri(String avatarUri) {
		this.avatarUri = avatarUri;
	}

	public String getPhotoUri() {
		return photoUri;
	}

	public void setPhotoUri(String photoUri) {
		this.photoUri = photoUri;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}

	public Date getModifyDate() {
		return modifyDate;
	}

	public void setModifyDate(Date modifyDate) {
		this.modifyDate = modifyDate;
	}

	public LvlType getLvl() {
		return lvl;
	}

	public void setLvl(LvlType lvl) {
		this.lvl = lvl;
	}

	public Long getLvlttl() {
		return lvlttl;
	}

	public void setLvlttl(Long lvlttl) {
		this.lvlttl = lvlttl;
	}

	public UserStatus getStatus() {
		return status;
	}

	public void setStatus(UserStatus status) {
		this.status = status;
	}

	public Date getLvlEnd() {
		return lvlEnd;
	}

	public void setLvlEnd(Date lvlEnd) {
		this.lvlEnd = lvlEnd;
	}

	@JSONField(serialize = false)
	public int getFlag() {
		boolean localAvoidDisturb = (avoidDisturb != null && avoidDisturb);
		boolean localLocPrivte = (locPrivate != null && locPrivate);
		int flag = 0;
		flag = (localAvoidDisturb ? flag |= MASK_AVOIDDISTURB : flag & (~MASK_AVOIDDISTURB));
		flag = (localLocPrivte ? flag |= MASK_LOCPRIVATE : flag & (~MASK_LOCPRIVATE));
		return flag;
	}

	public void setFlag(Integer flag) {
		if (flag != null) {
			this.avoidDisturb = (flag & MASK_AVOIDDISTURB) != 0;
			this.locPrivate = (flag & MASK_AVOIDDISTURB) != 0;
		}
	}

	public Boolean getLocPrivate() {
		return locPrivate;
	}

	public void setLocPrivate(Boolean locPrivate) {
		this.locPrivate = locPrivate;
	}

	public Boolean getAvoidDisturb() {
		return avoidDisturb;
	}

	public void setAvoidDisturb(Boolean avoidDisturb) {
		this.avoidDisturb = avoidDisturb;
	}

	public boolean isOnline() {
		return online;
	}

	public void setOnline(boolean online) {
		this.online = online;
	}

	public List<Order> getOrders() {
		return orders;
	}

	public void setOrders(List<Order> orders) {
		this.orders = orders;
	}

	public Location getLocation() {
		return location;
	}

	public void setLocation(Location location) {
		this.location = location;
	}
}
